using System;
using System.Collections.Generic;
using System.Text;
using WCSFContrib.ECommerceCatalog.BusinessEntities;
using System.Globalization;
using System.Data;
using WCSFContrib.ECommerceCatalog.CatalogData;
using WCSFContrib.ECommerceCatalog.BusinessEntities.Enums;
using System.Web.Security;
using WCSFContrib.ECommerceCatalog.Admin.Interfaces.Services;

namespace WCSFContrib.ECommerceCatalog.Admin.Services
{
    public class UsersProfilesService : IUsersProfilesService
    {
        private CatalogDataSet _catalogDataSet;

        public UsersProfilesService()
            : this(CatalogRepository.Instance)
        { }

        public UsersProfilesService(CatalogDataSet ds)
        {
            _catalogDataSet = ds;
        }        

        #region IUsersProfilesService Members

        public void CreateUserProfile(string userName)
        {
            _catalogDataSet.UserProfile.AddUserProfileRow(userName);
        }
        
        public ICollection<UserProfile> AllUsersProfiles
        {
            get
            {
                ICollection<UserProfile> usersProfiles = new List<UserProfile>();
                foreach (CatalogDataSet.UserProfileRow row in _catalogDataSet.UserProfile.Rows)
                {
                    usersProfiles.Add(TranslateFromUserProfileRowToUserProfileEntity(row));
                }
                return usersProfiles;
            }
        }

        public UserProfile GetUserProfileById(int userProfileId)
        {
            CatalogDataSet.UserProfileRow userProfileRow = _catalogDataSet.UserProfile.FindByUserProfileId(userProfileId);
            UserProfile userProfile;

            if (userProfileRow == null)
                return null;

            userProfile = TranslateFromUserProfileRowToUserProfileEntity(userProfileRow);

            return userProfile;
        }

        public UserProfile GetUserProfileByUserName(string userName)
        {
            DataRow[] rows = _catalogDataSet.UserProfile.Select(String.Format(CultureInfo.CurrentCulture, "User='{0}'", userName));
            if (rows != null && rows.Length > 0)
                return TranslateFromUserProfileRowToUserProfileEntity(rows[0] as CatalogDataSet.UserProfileRow);

            return null;
        }

        public void AddAddress(int userProfileId, Address address)
        {
            CatalogDataSet.AddressRow addressRow = TranslateFromAddressEntityToAddressRow(address);
            _catalogDataSet.Address.AddAddressRow(addressRow);
            
            CatalogDataSet.UserProfileRow userProfileRow = _catalogDataSet.UserProfile.FindByUserProfileId(userProfileId);

            if (userProfileRow == null)
                return;

            _catalogDataSet.UserProfile_Address.AddUserProfile_AddressRow(userProfileRow, addressRow);
        }

        public void UpdateAddress(int userProfileId, Address address)
        {
            if (address == null)
                return;

            CatalogDataSet.AddressRow addressRow = _catalogDataSet.Address.FindByAddressId(address.AddressId);

            if (addressRow == null)
                return;

            addressRow.Street = address.Street;
            addressRow.City = address.City;
            addressRow.State = address.State;
            addressRow.Country = address.Country;
            addressRow.Phone = address.Phone;
        }

        public void RemoveAddress(int userProfileId, int addressId)
        {
            CatalogDataSet.UserProfile_AddressRow userProfile_AddressRow = _catalogDataSet.UserProfile_Address.FindByUserProfileIdAddressId(userProfileId, addressId);
            CatalogDataSet.AddressRow addressRow = _catalogDataSet.Address.FindByAddressId(addressId);

            if (userProfile_AddressRow == null || addressRow == null)
                return;

            _catalogDataSet.UserProfile_Address.RemoveUserProfile_AddressRow(userProfile_AddressRow);
            _catalogDataSet.Address.RemoveAddressRow(addressRow);
        }

        public void AddPaymentMethod(int userProfileId, Payment payment)
        {
            CatalogDataSet.PaymentRow paymentRow = TranslateFromPaymentEntityToPaymentRow(payment);
            _catalogDataSet.Payment.AddPaymentRow(paymentRow);
            
            CatalogDataSet.UserProfileRow userProfileRow = _catalogDataSet.UserProfile.FindByUserProfileId(userProfileId);

            if (userProfileRow == null)
                return;

            _catalogDataSet.UserProfile_Payment.AddUserProfile_PaymentRow(userProfileRow, paymentRow);
        }

        public void UpdatePaymentMethod(int userProfileId, Payment payment)
        {
            if (payment == null)
                return;

            CatalogDataSet.PaymentRow paymentRow = _catalogDataSet.Payment.FindByPaymentId(payment.PaymentId);

            if (paymentRow == null)
                return;

            paymentRow.PaymentType = (int)payment.PaymentType;
            paymentRow.PaymentInfo = payment.PaymentInfo;
        }

        public void RemovePaymentMethod(int userProfileId, int paymentId)
        {
            CatalogDataSet.UserProfile_PaymentRow userProfile_PaymentRow = _catalogDataSet.UserProfile_Payment.FindByUserProfileIdPaymentId(userProfileId, paymentId);
            CatalogDataSet.PaymentRow paymentRow = _catalogDataSet.Payment.FindByPaymentId(paymentId);

            if (userProfile_PaymentRow == null || paymentRow == null)
                return;

            _catalogDataSet.UserProfile_Payment.RemoveUserProfile_PaymentRow(userProfile_PaymentRow);
            _catalogDataSet.Payment.RemovePaymentRow(paymentRow);
        }

        public Address GetAddressById(int addressId)
        {
            CatalogDataSet.AddressRow addressRow = _catalogDataSet.Address.FindByAddressId(addressId);
            Address address;

            if (addressRow == null)
                return null;

            address = TranslateFromAddressRowToAddressEntity(addressRow);

            return address;
        }

        public Payment GetPaymentById(int paymentId)
        {
            CatalogDataSet.PaymentRow paymentRow = _catalogDataSet.Payment.FindByPaymentId(paymentId);
            Payment payment;

            if (paymentRow == null)
                return null;

            payment = TranslateFromPaymentRowToPaymentEntity(paymentRow);

            return payment;
        }

        #endregion

        private UserProfile TranslateFromUserProfileRowToUserProfileEntity(CatalogDataSet.UserProfileRow userProfileRow)
        {
            UserProfile userProfile = new UserProfile();
            UsersProfilesService usersProfilesService = new UsersProfilesService(_catalogDataSet);

            userProfile.UserProfileId = userProfileRow.UserProfileId;
            userProfile.User = userProfileRow.User;

            CatalogDataSet.UserProfile_AddressRow[] userProfile_AddressRows = userProfileRow.GetUserProfile_AddressRows();

            foreach (CatalogDataSet.UserProfile_AddressRow userProfile_AddressRow in userProfile_AddressRows)
            {
                Address address = TranslateFromAddressRowToAddressEntity(userProfile_AddressRow.AddressRow);

                userProfile.Addresses.Add(address);
            }

            CatalogDataSet.UserProfile_PaymentRow[] userProfile_PaymentRows = userProfileRow.GetUserProfile_PaymentRows();

            foreach (CatalogDataSet.UserProfile_PaymentRow userProfile_PaymentRow in userProfile_PaymentRows)
            {
                Payment payment = TranslateFromPaymentRowToPaymentEntity(userProfile_PaymentRow.PaymentRow);
                userProfile.PaymentsMethods.Add(payment);
            }

            return userProfile;
        }

        private static Address TranslateFromAddressRowToAddressEntity(CatalogDataSet.AddressRow addressRow)
        {
            Address address = new Address();

            address.AddressId = addressRow.AddressId;
            address.Street = addressRow.Street;
            address.City = addressRow.City;
            address.State = addressRow.IsStateNull() ? null : addressRow.State;
            address.Country = addressRow.Country;
            address.Phone = addressRow.IsPhoneNull() ? null : addressRow.Phone;

            return address;
        }

        private static Payment TranslateFromPaymentRowToPaymentEntity(CatalogDataSet.PaymentRow paymentRow)
        {
            Payment payment = new Payment();

            payment.PaymentId = paymentRow.PaymentId;
            payment.PaymentType = (PaymentType)paymentRow.PaymentType;
            payment.PaymentInfo = paymentRow.IsPaymentInfoNull() ? null : paymentRow.PaymentInfo;

            return payment;
        }

        private CatalogDataSet.AddressRow TranslateFromAddressEntityToAddressRow(Address address)
        {
            CatalogDataSet.AddressRow addressRow = _catalogDataSet.Address.NewAddressRow();

            addressRow.Street = address.Street;
            addressRow.City = address.City;
            addressRow.State = address.State;
            addressRow.Country = address.Country;
            addressRow.Phone = address.Phone;

            return addressRow;
        }

        private CatalogDataSet.PaymentRow TranslateFromPaymentEntityToPaymentRow(Payment payment)
        {
            CatalogDataSet.PaymentRow paymentRow = _catalogDataSet.Payment.NewPaymentRow();

            paymentRow.PaymentType = (int)payment.PaymentType;
            paymentRow.PaymentInfo = payment.PaymentInfo;

            return paymentRow;
        }
    }
}
